import Clipboard from "clipboard"
import { decrypt } from "./crypto"
/**
 * 复制文本到剪贴板
 * @param text 文本内容
 */
export const copyText = (text: string) => {
  return new Promise((resolve, reject) => {
    // 创建一个button
    const fakeElement = document.createElement('button')

    const clipboard = new Clipboard(fakeElement, {
      // 要复制的文本
      text: () => text,
      action: () => 'copy',
      // 设置焦点元素
      container: document.body
    })

    // 操作成功的回调
    clipboard.on('success', e => {
      // 清理创建的事件和对象
      clipboard.destroy()
      resolve(e)
    })
    // 操作失败的回调
    clipboard.on('error', e => {
      clipboard.destroy()
      reject(e)
    })

    // 将创建的button元素添加到body
    document.body.appendChild(fakeElement)
    // 点击button
    fakeElement.click()
    // 将添加的button元素从body中移除
    document.body.removeChild(fakeElement)
  })
}

// 读取剪贴板
export const readClipboard = (): Promise<string> => {
  return new Promise((resolve, reject) => {
    // 使用浏览器自带的 navigator.clipboard.readText() 来访问系统剪切板，以读取系统剪切板的内容
    if (navigator.clipboard?.readText) {
      navigator.clipboard.readText().then(text => {
        if (!text) reject('剪贴板为空或者不包含文本')
        return resolve(text)
      })
    }
    else reject('浏览器不支持或禁止访问剪贴板，请使用快捷键 Ctrl + V')
  })
}

// 解析加密后的剪贴板内容
export const pasteCustomClipboardString = (text: string) => {
  // 剪贴板的内容
  let clipboardData
  try {
    // 解密成功则代表text是元素或者页面（若不是JSON字符串会报错）
    clipboardData = JSON.parse(decrypt(text))
  }
  catch {
    // 解密失败则代表text是普通文本
    clipboardData = text
  }
  return clipboardData
}

// 尝试解析剪贴板内容是否为Excel表格（或类似的）数据格式
export const pasteExcelClipboardString = (text: string): string[][] | null => {
  const lines: string[] = text.split('\r\n')

  if (lines[lines.length - 1] === '') lines.pop()

  let colCount = -1
  const data: string[][] = []
  for (const index in lines) {
    data[index] = lines[index].split('\t')

    if (data[index].length === 1) return null
    if (colCount === -1) colCount = data[index].length
    else if (colCount !== data[index].length) return null
  }
  return data
}